<template>
  <page-view v-loading="loading">
    <template v-slot:header>
      <div class="all-image-view">
        <!--  二维码图片所在的父视图 生成二维码必须有承载视图 当开始生成的时候才展示  -->
        <div
            v-for="(item, index) in selectRows"
            class="qrcode-content"
            :id="getTitleAndQrCodeIdByDataId(item.id)"
            v-show="showBk"
            ref="print"
        >
          <div
              :key="index"
              :id="getQrCodeIdByDataId(index)"
              class="qrcode-bk"
          >
            <div class="qrcode-pic" ref="codeItem"></div>
            <div class="qrcode-title">{{item.name}}{{index}}</div>
          </div>
        </div>
      </div>

      <!--  中间带logo的二维码  text为该二维码扫码可以获取的信息 -->
      <vue-qr id="logoQrCode" :logoSrc="imageUrl" text="https://www.baidu.com" :size="132"></vue-qr>

      <div class="footer">
        <el-button @click="batchCreatQrCodeClicked" plain>批量生成</el-button>
        <el-button @click="downloadQrCodeImagesClicked" plain>下载</el-button>
        <el-button @click="printQrCodeImgClicked" plain>打印</el-button>
      </div>
    </template>

    <el-table :data="tableData" border @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" width="100" type="index" align="center" />
      <el-table-column prop="name" label="转账来自" align="center">
        <template v-slot="scope">
          <div class="link-type" @click="nameClicked">{{scope.row.name}}</div>
        </template>
      </el-table-column>
      <el-table-column prop="address" label="地址" align="center"></el-table-column>
      <el-table-column prop="qrCode" label="二维码图片" align="center">
        <template v-slot="scope">
          <img style="width: 132px;height: 140px" :src="getRowQrCodeImageById(scope.row.id)" alt="暂未生成">
        </template>
      </el-table-column>
      <el-table-column prop="handel" label="操作" align="center">
        <template v-slot="scope">
          <el-button type="primary" @click="generateRowCode(scope.row)">生成二维码</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--  用来测试canvas截图后的图片是否达到期望值  -->
<!--    <div class="qrcode-pic">-->
<!--      <img :src="base64Image" alt="">-->
<!--    </div>-->

    <el-dialog
        fullscreen
        v-model="innerVisible"
        title="二维码打印"
        center
        append-to-body
        destroy-on-close
    >
      <div id="print" ref="print">
        <div v-for="(item, index) in allResults" class="qrcode-bk">
          <!--  直接显示 高度要能显示下额外的文本信息  -->
          <img :src="item.image" :key="index" alt="" width="132" height="140" />
        </div>
      </div>
      <template #footer>
        <el-button v-if="!hideFooter" type="primary" @click="handlePrint">开始打印</el-button>
      </template>
    </el-dialog>
  </page-view>
</template>

<script>
// 学习笔记：1.二维码的生成和打印是两个步骤 打印前先需要弹窗展示 然后再打印
// 2.二维码的生成 要看对生成的二维码有什么要求 如果只是单纯图片就简单多了 如果需要二维码某个位置还有附加信息展示 则需要使用canvas截图

import QRCode from "qrcodejs2";
import html2canvas from 'html2canvas';
import vueQr from 'vue-qr/src/packages/vue-qr.vue'
import likeIcon2 from '@/assets/like_s.png'
import print from 'vue3-print-nb';
import axios from 'axios';
import FormData from 'form-data';
import {downloadFileByFileInfo} from "@/utils/util";

export default {
  name: "WorkdemoDetail",
  components: {
    vueQr,
  },
  data() {
    return {
      tableData:[],
      loading:false,

      // 当需要生成二维码的时候 显示canvas承接标签
      showBk:false,

      // imageUrl: 'https://img0.baidu.com/it/u=3049998987,1866756846&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500',
      imageUrl:require('../../assets/like_s.png'),
      innerVisible:false,
      // 纯二维码图片
      allImages:[],
      // canvas生成的带标题和二维码的图片
      allImages2:[],
      // canvas生成的带标题和二维码的图片blob
      allBlobs:[],
      // 存放canvas生成的图片信息 元素为对象 image为图片base64链接 id为对应单元行唯一值（告知服务端时可以用到 有区分标记）
      allResults:[],
      hideFooter:false,

      // 选择的单元行
      selectRows:[],

      base64Image:'',
    }
  },
  created() {
    this.uploadDataReq();
  },
  mounted() {
    console.log('baseTag：', this.baseTag);
  },
  methods:{
    uploadDataReq() {
      let arr = [];
      for (let i = 0; i < 10; i += 1) {
        let text = `https://blog.csdn.net/weixin_42601136?name=${i}`
        const obj = {
          text,
          name:'张三',
          address:'湖北省武汉市洪山区东湖花木城',
          id:i,
        }
        arr.push(obj);
      }
      this.tableData = arr;
    },

    /**
     * 批量生产二维码
     */
    batchCreatQrCodeClicked() {
      if (this.selectRows.length == 0) {
        this.$message.warning('请选择要生成二维码的数据');
        return;
      }
      this.loading = true;
      this.showBk = true;
      this.$nextTick(()=> {
        const arr = this.selectRows;
        arr.forEach((item, index)=>{
          let codeItemId = index;
          // 获取指定显示二维码区域的标签
          let codeImageDiv = this.$refs.codeItem[codeItemId];
          codeImageDiv.innerHTML = "";
          let qrcode = new QRCode(codeImageDiv, {
            // 二维码内容
            text: item.text,
            width: 100,
            height: 100,
            render: 'table',
            colorDark: "#333333", //二维码颜色
            colorLight: "#ffffff", //二维码背景色
            correctLevel : QRCode.CorrectLevel.H
          })

          // 二维码生成以后再删除
          let childs = document.getElementsByClassName('qrcode-pic')[codeItemId].childNodes;
          document.getElementsByClassName('qrcode-pic')[codeItemId].removeChild(childs[0]);
        });
      })

      setTimeout(() => {
        this.saveQrCodeImg();
      }, 1500)
    },

    /**
     * 下载生成的二维码图片
     */
    downloadQrCodeImagesClicked() {
      if (this.selectRows.length == 0) {
        this.$message.warning('至少选择一条数据');
        return;
      }
      if (this.allImages2.length == 0) {
        this.$message.warning('请先生成二维码');
        return;
      }
      const arr = this.allImages2;
      for (const img of arr) {
        downloadFileByFileInfo(img, '二维码图片', 'png')
      }
      this.uploadDataReq();
    },

    /**
     * 将标题和二维码图片放到一起的标签id
     * @param dataId 单元行数据唯一值
     * @returns {string}
     */
    getTitleAndQrCodeIdByDataId(dataId) {
      return `titleQrCode-${dataId}`;
    },

    /**
     * 获取生成的二维码图片标签id
     * @param index
     * @returns {string}
     */
    getQrCodeIdByDataId(index) {
      return `myQrCode${index}`;
    },

    /**
     * 保存二维码图片
     */
    saveQrCodeImg() {
      const arr = this.selectRows;
      let images = [];
      let needDownload = false;
      for (let i = 0; i < arr.length; i += 1) {
        // 生成二维码之后其实是个img标签 所以获取完id之后还要获取到这个img 才能下载成功
        let canvasData = this.$refs.codeItem[i].getElementsByTagName('img')
        console.log('canvasData:', canvasData[0])
        // base64字符
        let img = canvasData[0].src;
        console.log('img:', img)
        // let img = ''
        images.push(img);

        if (needDownload) {
          let a = document.createElement("a");
          a.href = img;
          a.download = `二维码${i}.png`;
          a.click();
          a.remove()
        }
      }

      // 可以弹窗显示查看图片
      this.allImages = images;
      // console.log('images:', images);
      // this.innerVisible = false;

      // 直接下载中间带图片的二维码
      if (needDownload) {
        let logoDiv = document.getElementById('logoQrCode')
        let a = document.createElement("a");
        a.href = logoDiv.src;
        a.download = `logo.png`;
        a.click();
        a.remove();
      }

      // 等页面先刷新完毕 - 直接批量打印了
      this.$nextTick(() => {
        setTimeout(() => {
          //  如果二维码还需要额外的文本信息展示 则还需要使用canvas截图生成
          this.downloadResult();
        }, 1000)
      })
    },

    /**
     * 打印二维码按钮点击事件
     */
    printQrCodeImgClicked() {
      if (this.allResults.length == 0) {
        this.$message.warning('请先生成二维码');
        return;
      }
      // 先弹窗显示
      this.innerVisible = true;
    },

    /**
     * base64转化为blob
     * @param dataurl
     * @returns {*}
     */
    base64ToBlob(dataUrl) {
      let arr = dataUrl.split(','),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },

    /**
     * 通过二维码图片以及下面的文本 使用canvas截取生成新的图片(这种是想要二维码某个位置还能有额外信息展示 需要用到canvas)
     */
    downloadResult() {
      let needDownload = false;
      let imagesNew = [];
      let imagesBlob = [];
      for (let i = 0; i < this.selectRows.length; i += 1) {
        // 获取便签内的内容
        const temp = this.selectRows[i];
        let targetId = this.getTitleAndQrCodeIdByDataId(temp.id);

        // canvas操作的目标标签
        let canvasSubView = document.getElementById(targetId);
        let a = document.createElement('a');

        // html2canvas插件 绘制带文字的二维码
        html2canvas(canvasSubView).then(canvas => {
          // 画布绘制
          let dom = document.body.appendChild(canvas);
          dom.style.display = 'none';
          a.style.display = 'none';
          document.body.removeChild(dom);

          // 图片blob
          let blob = this.dataURLToBlob(dom.toDataURL('image/png'));
          // 根据blob转化为可以下载的链接 - 输出一个包含Blob数据的url
          let url = URL.createObjectURL(blob);
          console.log('当前索引生成的带文字图片链接：', url);
          imagesNew.push(url);
          imagesBlob.push(blob);
          this.convertImageBlobToBase64(blob, temp.id);

          // 如果需要下载的话
          if (needDownload) {
            let name = `二维码+标题${index}`;
            a.setAttribute('href', url);
            // 图片名称
            a.setAttribute('download', name + '.png')
            document.body.appendChild(a);
            a.click();
            URL.revokeObjectURL(blob);
            document.body.removeChild(a);
          }
        });
      }

      setTimeout(() => {
        console.log("canvas截图后生成的所有带额外信息的图片数组", imagesNew);
        this.allImages2 = imagesNew;
        this.allBlobs = imagesBlob;
        this.innerVisible = false;
        console.log('this.allResults:', this.allResults);
        this.showBk = false;
        this.loading = false;
        this.$message.success('二维码生成成功，可以打印了');
      }, 2000)
    },

    /**
     *
     * @param dataUrl
     * @returns {*}
     */
    dataURLToBlob(dataUrl) {
      let arr = dataUrl.split(','), mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime })
    },


    /**
     * 打印二维码
     */
    handlePrint() {
      this.hideFooter = true;
      this.$nextTick(()=> {
        // 打印时 先让弹窗底部按钮隐藏
        window.print()
      })
      const formData = new FormData();
      formData.append('image', {
        url: this.allImages2[0],
        type: 'image/jpeg',
        name: 'image.jpg',
      });

      axios.post('http://example.com/upload', formData).then(response => {
        console.log(response);
      }).catch(error => {
        console.error(error);
      });
    },

    /**
     * 将图片链接Blob数据转化为base64字符
     * @param blob 图片blob数据
     * @param dataId 生成该二维码图片的单元行唯一值
     */
    convertImageBlobToBase64(blob, dataId) {
      const reader = new FileReader();
      let arr = this.allResults;
      reader.onload = (e) => {
        const base64Image = e.target.result;
        this.base64Image = base64Image;
        // 防止图片生产重复
        let isIn = arr.some(item => item.id == dataId);
        if (!isIn) {
          const imageInfo = {
            image:base64Image,
            id:dataId,
          }
          arr.push(imageInfo);
        }
        this.allResults = arr;
        if (arr.length == this.selectRows.length) {
          // 图片生产完毕
          this.showBk = false;
        }
        // 图片生产完毕 移除该div
        let divId = this.getTitleAndQrCodeIdByDataId(dataId);
        let canvasBkDiv = document.getElementById(divId);
        canvasBkDiv.style.display = 'none';
      };
      reader.readAsDataURL(blob);
    },

    /**
     * 生成某个单元行二维码
     * @param row 该单元行数据源
     */
    generateRowCode(row) {
      let image = this.getRowQrCodeImageById(row.id);
      if (!image) {
        this.selectRows = [row];
        this.batchCreatQrCodeClicked();
      } else {
        this.$message.warning('该数据二维码已经生成，请直接打印');
      }
    },

    /**
     * 打印某个单元行二维码
     * @param row 该单元行数据源
     */
    printRowCode(row) {

    },

    /**
     * 单元格多选方法
     * @param val
     */
    handleSelectionChange(selection) {
      this.selectRows = selection;
      console.log('当前选择的单元格数据', this.selectRows);
    },

    /**
     * 获取某个单元行生产的二维码图片
     */
    getRowQrCodeImageById(dataId) {
      let image = '';
      for (const obj of this.allResults) {
        if (obj.id == dataId) {
          image = obj.image;
          break;
        }
      }
      return image;
    },
  }
}
</script>

<style scoped>

.content {

}

.qrcode-bk {
  display: inline-block;
  text-align: center;
  margin:10px 10px;
}

/*所有临时生成二维码区域*/
.all-image-view {
  display: flex;
  flex-wrap: wrap;
  margin-right: 10px;
}

/*每个承载二维码图片和标题的父标签 用以做画布截取范围*/
.qrcode-content {
  width:132px;
  background-color: #f3f4f5;
}

.qrcode-pic {
  width:100px;
  height:100px;
  background-color: #fff;
  padding: 6px;
  box-sizing: border-box;
}

/*二维码标题*/
.qrcode-title {
  font-size: 14px;
  width: 100px;
  margin-top: 10px;
}

.footer {
  margin-top: 20px;
  margin-bottom: 10px;
}

.dialog-footer {
  display: block;
}
</style>
